package com.xyy.saas.payment.util.mq;

import com.alibaba.fastjson.JSON;
import com.xyy.saas.payment.adpater.yzh.constant.ConfigPath;
import com.xyy.saas.payment.adpater.yzh.constant.DataDict;
import com.xyy.saas.payment.adpater.yzh.util.HttpUtil;
import com.xyy.saas.payment.adpater.yzh.util.YzhResultParseUtil;
import com.xyy.saas.payment.adpater.yzh.vo.WXPayOrderResp;
import com.xyy.saas.payment.adpater.yzh.vo.WxpayOrder;
import com.xyy.saas.payment.common.RocketMqGroup;
import com.xyy.saas.payment.common.RocketMqTopic;
import com.xyy.saas.payment.cores.enums.TransactionStatusEnum;
import com.xyy.saas.payment.cores.vo.CallbackResultVo;
import com.xyy.saas.payment.dao.model.WXPayRecord;
import com.xyy.saas.payment.manager.WXPayManager;
import com.xyy.saas.payment.service.WXPayRecordService;
import com.xyy.saas.payment.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Map;

@Service
@RocketMQMessageListener(topic = RocketMqTopic.TOPIC_ASYNC_WX_PAY, consumerGroup = RocketMqGroup.GROUP_WX_PAY_CONSUMER, consumeMode = ConsumeMode.ORDERLY)
public class WXPayConsumer implements RocketMQListener<MessageExt>, RocketMQPushConsumerLifecycleListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(WXPayConsumer.class);

    @Autowired
    private WXPayManager wxPayManager;
    @Autowired
    private WXPayRecordService wxPayRecordService;

    @Override
    public void onMessage(MessageExt messageExt) {
        String payNo = new String(messageExt.getBody());
        LOGGER.info("WXPayConsumer#onMessage MQ receive message body:{}.", payNo);

        if(StringUtils.isBlank(payNo)) {
            LOGGER.error("WXPayConsumer#onMessage MQ receive message fail payNo is blank.");
            return;
        }

        // 1.校验数据
        WXPayRecord wxPayRecord = wxPayRecordService.queryByPayNo(payNo);

        if(null == wxPayRecord) {
            LOGGER.error("WXPayConsumer#onMessage query wxPayRecord is not exist. payNo:{}", payNo);
            return;
        }

        LOGGER.info("WXPayConsumer#onMessage query wxPayRecord:{}", JSONUtils.toJSON(wxPayRecord));

        //2.校验状态
        if(wxPayRecord.getStatus() != Integer.parseInt(TransactionStatusEnum.TRANSACTING.getCode())) {
            LOGGER.warn("WXPayConsumer#onMessage wxPayRecord status is not TRANSACTING status");
            return;
        }

        // 3.请求云账户-微信支付
        WxpayOrder wxpayOrder = WxpayOrder.build(wxPayRecord.getPayNo(), wxPayRecord.getRealName(),
                wxPayRecord.getIdCard(), wxPayRecord.getOpenid(), ApolloUtil.getProperty(ConfigPath.WX_YZH_WX_APP_ID), AmountCastUtil.castFen2Yuan(wxPayRecord.getAmount()), wxPayRecord.getRemark());
        Map<String, Object> result = null;

        try {
            LOGGER.info("WXPayConsumer#onMessage request yzh# param:{}", JSONUtils.toJSON(wxpayOrder));
            result = HttpUtil.post(wxpayOrder.assembleRequest(ConfigPath.HY_WX_PAY), ApolloUtil.getProperty(ConfigPath.WX_YZH_PAY_ORDER));
        }
        catch(Exception e) {
            LOGGER.error("WXPayConsumer#onMessage request yzh异常# param=" + JSONUtils.toJSON(wxpayOrder), e);
        }

        LOGGER.info("WXPayConsumer#onMessage yzh# result:{}", JSONUtils.toJSON(result));

        // 4.解析返回值
        WXPayOrderResp wxPayOrderResp = YzhResultParseUtil.parseWXPayApplyResult(result);

        // 请求失败order_id为空
        if(StringUtils.isBlank(wxPayOrderResp.getOrder_id())) {
            wxPayOrderResp.setOrder_id(payNo);
        }

        // 5.更新下单记录
        wxPayManager.updateWXPayStatus(wxPayOrderResp);

        // 6.回调：这里只有请求外部失败才回调，否则依赖三方回调后再通知业务
        if(!DataDict.SUCCESS_CODE.equals(wxPayOrderResp.getCode())) {
            wxPayManager.wxPayCallback(CallbackResultVo.TYPE_WX_PAY_FAIL, wxPayRecord.getCallback(),
                    wxPayRecord.getPayNo(), wxPayRecord.getBusinessNo(), wxPayOrderResp.getFailMsg(), LocalDateTime.now());
        }

        LOGGER.info("WXPayConsumer#onMessage apply_wx_pay end payNo:{}, result:{}", payNo, JSON.toJSON(result));
    }

    @Override
    public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {
        defaultMQPushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        defaultMQPushConsumer.setConsumeTimestamp(UtilAll.timeMillisToHumanString3(System.currentTimeMillis()));
    }
}
